home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / prog / unld8616.arj / UNLOAD86.A86 < prev    next >
Text File  |  1994-04-01  |  27KB  |  829 lines

  1. ;************************************************************************
  2. ;*                                    *
  3. ;*    UNLOAD86.A86  This is a MS-DOS unload program.    See the help    *
  4. ;*    screen at the end of this file for details on its use.        *
  5. ;*    Written by:  Mark D. Pickerill 9 Aug. 1988            *
  6. ;*    Assemble with the 2500 A.D. X8086 assembler.            *
  7. ;*                                    *
  8. ;************************************************************************
  9.                 ;
  10. CR:    EQU    0DH        ; Carriage return
  11. LF:    EQU    0AH        ; Line feed
  12. EOF:    EQU    1AH        ; End of file
  13.                 ;
  14.       ASSUME CS:NOTHING,DS:NOTHING,ES:NOTHING
  15.                 ;
  16.     CHIP    8086        ; 8086 mode
  17.                 ;
  18.     ORG    0100H        ; Start of tpa
  19.                 ;
  20. UNLOAD:    JMP    SHORT START    ; Skip data area
  21.                 ;
  22. FILDAT:                ;
  23.     DB    0FFH        ; Data to fill empty space in rom (if selected)
  24. BNPFTYP:            ;
  25.     DB    'PN'        ; Pn for bnpf, hl for bhlf, or 10 for b10f
  26. FTYPE:                ;
  27.     DB    '.HEX',00H    ; File type
  28. FTYPE1:                ;
  29.     DB    '.BNP',00H    ; File type for bnpf files
  30. DOEOF:                ;
  31.     DB    00H        ; Zero for no eof (cntrl-z, 1ah) on end of file
  32.                 ; End of user patchable options
  33. NUMTERM:            ; 0 means UNIX style LF only termination
  34.     DB    02H        ; 1 means TRS-80/MAC CR only termination
  35. ACR:                ; 2 means standard MS-DOS or CP/M CRLF term.
  36.     DB    0DH        ; The first terminator
  37. ALF:                ;
  38.     DB    0AH        ; The second...
  39. OUTTYPE:            ;
  40.     DB    00H        ; 00 for hex, non-zero for bnpf
  41. USELIN:                ;
  42.     DB    00H        ; 00 for no extended linear address
  43. USEEXT:                ;
  44.     DB    00H        ; 00 for no extended address records
  45. DOFILL:                ;
  46.     DB    00H        ; 00 not to fill to end of rom
  47. OVERRIDE:            ;
  48.     DB    00H        ; Ff if overriding forced extended addressing
  49. ENDSEG:                ;
  50.     DW    0000H        ; Space to store end segment for rom fill
  51. ENDADDR:            ;
  52.     DW    0000H        ; Space to store end address for rom fill
  53. OOD:                ;
  54.     DB    00H        ; Flag 0 for read from disk, ff to use fildat
  55. RAWHEX:                ;
  56.     DB    00H        ; For straight ASCII hex...
  57.                 ;
  58. NOPARMS:JMP    HELP        ; Extend short jump
  59.                 ;
  60. START:    PUSH    CS        ; Set data segment
  61.     POP    DS        ; It's set
  62.     PUSH    DS        ; Get this segment
  63.     POP    ES        ; And set es as well
  64.     CALL    ILPRT        ; Print signon message
  65.     DB    CR,LF,'UNLOAD86 ver. 1.6',00H    
  66.                 ;
  67.     MOV    SI,0080H    ; Point to parameter field in psp
  68.     LODSB            ; Get parameter length
  69.     MOV    CL,AL        ; Into cl
  70.     OR    CL,CL        ; Force flags
  71.     JZ    NOPARMS        ; Print help screen
  72.     MOV    CH,00H        ; Zero ch
  73. LOOP1:    LODSB            ; Get byte from parameter field
  74.     CMP    AL,' '        ; Space?
  75.     LOOPZ    LOOP1        ; Wait until you get a non-space char
  76.     JZ    NOPARMS        ; Just spaces, print help screen
  77.     CMP    AL,'/'        ; Switch char?
  78.     JZ    NOPARMS        ; No filename!, print help screen
  79.     CMP    AL,'-'        ; Alt switch for unix types
  80.     JZ    NOPARMS        ; No filename!, print help screen
  81.     CMP    AL,'['        ; Alt switch for cp/m types
  82.     JZ    NOPARMS        ; No filename!, print help screen
  83.     LEA    DI,INFN        ; Point to input filename area
  84.     STOSB            ; Stuff this char
  85. LOOP2:    LODSB            ; Get byte
  86.     CMP    AL,' '        ; Space?
  87.     JZ    NOSP        ; Yes,ignore
  88.     CMP    AL,'/'        ; Or switch char?
  89.     JZ    SWITCH        ; Yes
  90.     CMP    AL,'-'        ; Alt switch for unix types
  91.     JZ    SWITCH        ; Yes
  92.     CMP    AL,'['        ; Alt switch for cp/m types
  93.     JZ    SWITCH        ; Yes
  94.     STOSB            ; Stuff char
  95. NOSP:    LOOP    LOOP2        ; Nope
  96.     JMP    CONT        ; No more
  97. SWITCH:    LODSB            ; Get switch options
  98.     AND    AL,5FH        ; Make upper case as ibm types
  99.                 ; Usualy use lower case!
  100.     CMP    AL,'B'        ; Bnpf option?
  101.     JZ    SETBNPF        ; Yes
  102.     CMP    AL,'O'        ; Override forced extended address records?
  103.     JZ    SETOVR        ; Yes
  104.     CMP    AL,'E'        ; Use extended addressing?
  105.     JZ    SETEXT        ; Yes
  106.     CMP    AL,'P'        ; Set eprom type?
  107.     JZ    SETROM        ; Yes
  108.     CMP    AL,'L'        ; Use extended linear addressing?
  109.     JZ    SETLIN        ; Yes
  110.     CMP    AL,'Z'        ; Put control-z at end of file?
  111.     JZ    SETEOF        ; Yes
  112.     CMP    AL,'H'        ; Do raw hex?
  113.     JZ    SETRAW        ; Yes
  114.     CMP    AL,'T'        ; CR only type output?
  115.     JZ    SETCR        ; Yes
  116.     CMP    AL,'U'        ; LF only type output?
  117.     JZ    SETLF        ; Yes
  118.     LOOP    SWITCH        ; Look for more options
  119.     JMP    CONT        ; No more
  120.                 ;
  121. SETOVR:    XOR    AL,AL        ; Turn off extended addressing
  122.     MOV    [USEEXT],AL    ; Do it
  123.     MOV    [USELIN],AL    ; Turn off extended linear addressing
  124.     DEC    AL        ; Indicate override of extended addressing
  125.     MOV    [OVERRIDE],AL    ; Flag it as such
  126.     LOOP    SWITCH        ; Look for more options
  127.     JMP    CONT        ; No more
  128.                 ;
  129. SETEXT:    XOR    AL,AL        ; Turn off extended linear addressing
  130.     MOV    [USELIN],AL    ; Do it
  131.     DEC    AL        ; Indicate use of extended addressing
  132.     MOV    [USEEXT],AL    ; Flag it as such
  133.     LOOP    SWITCH        ; Look for more options
  134.     JMP    CONT        ; No more
  135.                 ;
  136. SETLIN:    XOR    AL,AL        ; Turn off extended addressing
  137.     MOV    [USEEXT],AL    ; Do it
  138.     MOV    [DOFILL],AL    ; Turn off fill to end of rom
  139.     DEC    AL        ; Get an ff
  140.     MOV    [OVERRIDE],AL    ; Flag extended override
  141.     MOV    [USELIN],AL    ; Flag use of extended linear addressing
  142.     LOOP    SWITCH        ; Look for more options
  143.     JMP    CONT        ; No more options
  144.                 ;
  145. SETBNPF:NOT    BYTE PTR [OUTTYPE] ; Indicate bnpf option
  146.     JMP    SHORT LOOKMOR    ; Look for more options
  147.                 ;
  148. SETEOF:    NOT    BYTE PTR [DOEOF] ; Put eof at end of file
  149.                 ;
  150. LOOKMOR:LOOP    SWITCH        ; If more, look for additional options
  151.     JMP    CONT        ; No more
  152.                 ;
  153. SETRAW:    MOV    [RAWHEX],BYTE PTR 0FFH ; Turn on raw hex option
  154.     JMP    SHORT LOOKMOR    ; And look for more options
  155.                 ;
  156. SETLF:    MOV    [NUMTERM],BYTE PTR 00H ; Setup for UNIX LF only
  157.     JMP    SHORT LOOKMOR    ; And look for more
  158.                 ;
  159. SETCR:    MOV    [NUMTERM],BYTE PTR 01H ; Setup for TRS-80/MACintosh CR only
  160.     JMP    SHORT LOOKMOR    ; Go look for more options
  161.                 ;
  162. SETROM:    MOV    [USELIN],BYTE PTR 00H ; Turn off linear extended addressing
  163.     DEC    CX        ; Decrement loop counter
  164.     LODSB            ; Get char
  165.     CMP    AL,'0'        ; At least a zero?
  166.     JC    LOOKMOR        ; No,ignore
  167.     CMP    AL,'A'        ; At least an a?
  168.     JC    NUM        ; Numeric
  169.     AND    AL,5FH        ; Force upper case
  170.     CMP    AL,'G'        ; More garbage?
  171.     JNC    LOOKMOR        ; Yes, ignore
  172.     SUB    AL,37H        ; Remove alpha bias
  173.     JMP    SHORT FOUNDIT    ; And continue
  174. NUM:    CMP    AL,3AH        ; Above numeric?
  175.     JNC    LOOKMOR        ; Yes, ignore
  176.     SUB    AL,30H        ; Remove numeric bias
  177. FOUNDIT:CMP    AL,0CH        ; Big rom?
  178.     JC    SMALL        ; No
  179.     CALL    CHKOVR        ; Unless user has overridden
  180. SMALL:    PUSH    SI        ; Save pointer
  181.     LEA    SI,ATABLE    ; Point to address table
  182.     ADD    AL,AL        ; Multiply by two
  183.     ADD    AL,AL        ; And by four
  184.     XOR    AH,AH        ; Clear ah
  185.     ADD    SI,AX        ; Add in offset
  186.     LODSW            ; Get segment address
  187.     MOV    [ENDSEG],AX    ; Stuff it
  188.     LODSW            ; Get offset address
  189.     MOV    [ENDADDR],AX    ; Stuff it
  190.     MOV    [DOFILL],BYTE PTR 0FFH ; Flag fillrom operation
  191.     POP    SI        ; Restore si
  192.     JMP    LOOKMOR        ; Go look for more options
  193.                 ;
  194. CONT:    MOV    [DI],BYTE PTR 00H ; Terminate string
  195.     LEA    SI,INFN        ; Copy input to output fn
  196.     LEA    DI,OUTFN    ; Pointing to output filename
  197.     MOV    CX,60D        ; 64-4 for 'hex0' is 60
  198. LOOP3:    LODSB            ; Get byte
  199.     STOSB            ; Stash it (need it in al, movsb won't work)
  200.     CMP    AL,'.'        ; Looking for that file extension
  201.     JZ    DONE        ; Found the dot
  202.     CMP    AL,00H        ; End?
  203.     LOOPNZ    LOOP3        ; Continue
  204. DONE:    DEC    DI        ; Backup over dot or zero
  205.     MOV    CX,0005H    ; Five bytes to move
  206.     MOV    AL,[OUTTYPE]    ; Hex or bnpf?
  207.     OR    AL,AL        ; Force flags
  208.     JZ    OHEX        ; Hex
  209.     LEA    SI,FTYPE1    ; Point to file type for bnpf
  210.     JMP    SHORT ALL    ; And continue
  211. OHEX:    LEA    SI,FTYPE    ; Point to file type for hex
  212. ALL:    REP    MOVSB        ; Move the rest
  213.                 ;
  214.     MOV    AL,00H        ; Read access code
  215.     MOV    AH,3DH        ; Open file function
  216.     LEA    DX,INFN        ; Point to input file name
  217.     INT    21H        ; Open the file
  218.     MOV    [INHDL],AX    ; Save handle
  219.     JNC    OK        ; Ok
  220.     CALL    ILPRT        ; Print this...
  221.     DB    CR,LF,'Failure to Open Input file',00H
  222.     JMP    FINIS        ; Go to error handler
  223.                 ;
  224. OK:    CMP    [NUMTERM],BYTE PTR 00H ; Unix configuration?
  225.     JNZ    TERMOK        ; No, it's OK
  226.     MOV    [NUMTERM],BYTE PTR 01H ; Force to 1...
  227.     MOV    AL,[ALF]    ; Get LF
  228.     MOV    [ACR],AL    ; And make 00 mean LF termination...
  229.     MOV    [CNTRLB+1],AL    ; And fix BNPF start sequence
  230.     MOV    [CNTRLC+1],AL    ; And fix BNPF end sequence
  231.     MOV    [EOFREC+11D],AL    ; Fix hex EOF record
  232.                 ;
  233. TERMOK:    CMP    CS:[RAWHEX],BYTE PTR 00H ; Check for raw hex
  234.     JZ    OKK        ; Not raw hex
  235.     XOR    AL,AL        ; A zero
  236.     MOV    [USELIN],AL    ; Turn off linear records
  237.     MOV    [USEEXT],AL    ; And extended records
  238.     MOV    [DOFILL],AL    ; No fill to end
  239.     MOV    [OVERRIDE],AL    ; No override of extended recs, meaningless
  240.                 ;
  241. OKK:    MOV    BX,AX        ; Handle in bx
  242.     MOV    AX,4202H    ; Move to end of file
  243.     XOR    CX,CX        ; Clear offsets
  244.     MOV    DX,CX        ; Including dx
  245.     INT    21H        ; Do it
  246.     OR    DX,DX        ; Longer than 64k?
  247.     JZ    LT64K        ; No
  248.     CALL    CHKOVR        ; Check extended addressing override
  249.                 ;
  250. LT64K:    XOR    CX,CX        ; Clear offsets
  251.     MOV    DX,CX        ; All 32 bits
  252.     MOV    AX,4200H    ; Move back to start of file
  253.     MOV    BX,[INHDL]    ; Get handle
  254.     INT    21H        ; Moved back
  255.     MOV    CL,00H        ; Normal addributes
  256.     MOV    AH,3CH        ; Create file function
  257.     LEA    DX,OUTFN    ; Point to file name
  258.     INT    21H        ; Open the file
  259.     JNC    OK1        ; Ok
  260.     CALL    ILPRT        ; Print this...
  261.     DB    CR,LF,'Failure to Open output file',00H
  262.     JMP    FINIS        ; Go to error handler
  263. OK1:    MOV    [OUTHDL],AX    ; Save handle
  264.     MOV    AL,[OUTTYPE]    ; Get output format
  265.     OR    AL,AL        ; Force flags
  266.     JZ    READ        ; Don't do start char for bnpf
  267.     LEA    DX,CNTRLB    ; Point to start byte
  268.     MOV    CL,[NUMTERM]     ; Get number of termination characters...
  269.     XOR    CH,CH        ; Zero upper
  270.     INC    CX        ; To conpensate for cntrl-b!
  271.     CALL    DSKWRT        ; Write it
  272.     JNC    READ        ; Ok
  273.     JMP    BADWR        ; Error
  274.                 ;
  275. READ:    LEA    DI,INBUF    ; Point to input buffer
  276.     MOV    CX,16D        ; Fill entire buffer
  277.     MOV    AL,[FILDAT]    ; Get fill data
  278.     MOV    AH,AL        ; Dup into ah
  279.     REP    STOSW        ; Do it
  280.                 ;
  281.     MOV    AL,[OOD]    ; Already out of data?
  282.     OR    AL,AL        ; Force flags
  283.     JNZ    FILLIT        ; Yup
  284.     LEA    DX,INBUF    ; Point to buffer
  285.     MOV    BX,[INHDL]    ; Get handle
  286.     CALL    DSKRD        ; Go get data
  287.     JNC    ROK        ; Ok
  288.     CALL    ILPRT        ; Print this...
  289.     DB    CR,LF,'Error Reading Input file',00H
  290.     JMP    FINIS        ; Go to error handler
  291.                 ;
  292. CNTRLB:                ;
  293.     DB    02H,CR,LF    ; Bnpf start
  294.                 ;
  295. ROK:    OR    AX,AX        ; Completely finished?
  296.     JNZ    NOPE        ; Nope
  297.     MOV    AL,[OUTTYPE]    ; Check for bnpf
  298.     OR    AL,AL        ; Force flags
  299.     JNZ    EXIT        ; Bnpf ignores all this...
  300.     MOV    AL,0FFH        ; Indicate we're finished reading from disk
  301.     MOV    [OOD],AL    ; Flag it
  302.     MOV    AL,[DOFILL]    ; Check for fillrom function
  303.     OR    AL,AL        ; Force flags
  304.     JZ    EXIT        ; Not selected
  305. FILLIT:    MOV    AX,[EXTEND]    ; Get current segment
  306.     SUB    AX,1000H    ; Compensate to what is in use
  307.     CMP    [ENDSEG],AX    ; Check against selected end segment
  308.     JC    TOOBIG        ; Warn operator that his data won't fit
  309.     JNZ    NOPE        ; Segment hasn't been reached yet, continue
  310.     MOV    AX,[ADDRESS]    ; Get current address
  311.     DEC    AX        ; To last location, not next avail loc
  312.     CMP    [ENDADDR],AX    ; Check against selected end address
  313.     JC    TOOBIG        ; Warn operator that his data won't fit
  314.     JNZ    NOPE        ; Address hasn't been reached yet
  315.                 ;
  316. EXIT:    JMP    FINISHUP    ; Yes, finish up & terminate
  317. TOOBIG:    JMP    WARN        ; Tell operator
  318. NOPE:    MOV    AL,[OUTTYPE]    ; Get output format
  319.     OR    AL,AL        ; Force flags
  320.     JZ    HEX        ; Do hex
  321.                 ; Drop through to bnpf
  322.     LEA    SI,INBUF    ; Point to input buffer
  323.     MOV    CX,32D        ; 32 bytes to process
  324. BNPF:    LEA    DI,OUTBUF    ; Output buffer
  325.     MOV    [DI],BYTE PTR 'B' ; The b for begin
  326.     INC    DI        ; Next location
  327. BIGLP:    LODSB            ; Get byte
  328.     PUSH    CX        ; Save byte loop
  329.     MOV    CX,0008H    ; 8 bits in a byte
  330. BNPFLP:    RCL    AL,1        ; Rotate through carry
  331.     JC    P        ; High
  332.     MOV    AH,[BNPFTYP+1]    ; Get the byte for low
  333.     MOV    [DI],AH        ; Put in buffer
  334.     INC    DI        ; Next location
  335.     LOOP    BNPFLP        ; Do entire byte
  336.     JMP    ONEBYTE        ; Complete & write
  337. P:    MOV    AH,[BNPFTYP]    ; Get the byte for high
  338.     MOV    [DI],AH        ; Put in buffer
  339.     INC    DI        ; Next location
  340.     LOOP    BNPFLP        ; Do entire byte
  341. ONEBYTE:MOV    [DI],BYTE PTR 'F' ; The f for finish
  342.     POP    CX        ; Recover byte loop
  343.     INC    DI        ; Next dest
  344.                 ;
  345.     MOV    AL,[ACR]    ; Get first terminator
  346.     STOSB            ; Append it
  347.     MOV    BP,11D        ; Assume eleven bytes every time
  348.     CMP    [NUMTERM],BYTE PTR 02H ; Two terminations?
  349.     JNZ    SKIPLF1        ; No, skip
  350.     MOV    AL,[ALF]    ; Get second terminator
  351.     STOSB            ; Append it
  352.     INC    BP        ; And write 12 bytes!
  353.                 ;
  354. SKIPLF1:PUSH    CX        ; Save loop counter
  355.     PUSH    SI        ; Save input counter
  356.     MOV    CX,BP        ; Get number to write...
  357.     CALL    WRITE        ; Write byte
  358.     POP    SI        ; Recover input counter
  359.     POP    CX        ; Recover loop counter
  360.     LOOP    BNPF        ; Do next byte
  361.     JMP    READ        ; Read next 32 bytes
  362.                 ;
  363. HEX:    XOR    BX,BX        ; Output counter
  364.     MOV    CX,32D        ; Input counter
  365.     XOR    DX,DX        ; Dl is checksum reg
  366.     MOV    AX,[ADDRESS]    ; Get current load address
  367.     OR    AX,AX        ; Force flags
  368.     JNZ    NOEXT        ; No extended address record needed
  369.     CALL    EAR        ; Do extended addressing if selected
  370. NOEXT:    LEA    SI,INBUF    ; Point to input buffer
  371.     LEA    DI,OUTBUF    ; Point to output buffer
  372.     MOV    AL,[RAWHEX]    ; Check for raw hex
  373.     OR    AL,AL        ; Force flags
  374.     JNZ    LOOP4        ; Raw hex does no colons, addresses, etc...
  375.                 ;
  376.     MOV    [DI],BYTE PTR ':' ; Stuff that colon
  377.     INC    DI        ; And point to next
  378.     INC    BX        ; And increment counter
  379.     MOV    AL,20H        ; All are 32 byte records
  380.     CALL    BITE        ; Stuff it
  381.     MOV    AX,[ADDRESS]    ; Get load address
  382.     XCHG    AL,AH        ; Do high byte first
  383.     CALL    BITE        ; Send it
  384.     XCHG    AH,AL        ; Now do low byte
  385.     CALL    BITE        ; Send it
  386.     MOV    AX,[ADDRESS]    ; Get load address
  387.     ADD    AX,20H        ; Increment to next
  388.     MOV    [ADDRESS],AX    ; Put back
  389.     MOV    AL,00H        ; Record type 00
  390.     CALL    BITE        ; Send it
  391. LOOP4:    LODSB            ; Get input
  392.     CALL    BITE        ; Process
  393.     LOOP    LOOP4        ; Until done
  394.     MOV    AL,DL        ; Get checksum
  395.     CMP    CS:[RAWHEX],BYTE PTR 00H ; Check for raw hex...
  396.     JNZ    SKIPCS        ; Raw hex does no checksums either...
  397.                 ;
  398.     CALL    BITE        ; Process, [clobbering dl]
  399. SKIPCS:    MOV    AL,[ACR]    ; Get first terminator
  400.     STOSB            ; Append it
  401.     INC    BX        ; Bump output counter appropiately
  402.     CMP    [NUMTERM],BYTE PTR 02H ; Two terminations?
  403.     JNZ    SKIPLF        ; No, skip
  404.     MOV    AL,[ALF]    ; Get second terminator
  405.     STOSB            ; Append it
  406.     INC    BX        ; Bump output counter appropiately
  407.                 ;
  408. SKIPLF:    MOV    CX,BX        ; Get count into cx
  409.     CALL    WRITE        ; Write output
  410.     JMP    READ        ; Read more
  411.                 ;
  412. WRITE:    LEA    DX,OUTBUF    ; Point to beginning of output buffer
  413.     MOV    BX,[OUTHDL]    ; Get output handle
  414.     CALL    DSKWRT        ; Write data
  415.     JNC    WOK        ; Ok
  416. BADWR:    CALL    ILPRT        ; Print this...
  417.     DB    CR,LF,'Error Writing Output file',00H
  418.     JMP    FINIS        ; Go to error handler
  419. WOK:    RET            ; Near
  420.                 ;
  421. EAR:    PUSH    AX        ; Save everything
  422.     MOV    AL,[USEEXT]    ; Get extended address flag
  423.     OR    AL,[USELIN]    ; Or in extended linear flag
  424.     JNZ    GOAHEAD        ; If either set, go do it!
  425.                 ;
  426.     MOV    AX,[EXTEND]    ; Get extended address anyway
  427.     ADD    AX,1000H    ; Increment to next 64k block
  428.     MOV    [EXTEND],AX    ; Put back for consistancy
  429.     POP    AX        ; Restore ax
  430.     RET            ; Go home
  431.                 ;
  432. GOAHEAD:PUSH    DI        ;
  433.     PUSH    CX        ;
  434.     PUSH    DX        ;
  435.     PUSH    SI        ;
  436.     PUSH    BX        ;
  437.     LEA    DI,OUTBUF    ; Point to output buffer
  438.     MOV    [DI],BYTE PTR ':' ; Stuff that colon
  439.     INC    DI        ; And point to next
  440.     INC    BX        ; And increment counter
  441.     MOV    AL,02H        ; Two bytes of data in extended record
  442.     CALL    BITE        ; Stuff it
  443.     MOV    AX,0000H    ; Extended address records have load addr of 0
  444.     XCHG    AL,AH        ; Do high byte first
  445.     CALL    BITE        ; Send it
  446.     XCHG    AH,AL        ; Now do low byte
  447.     CALL    BITE        ; Send it
  448.     CMP    BYTE PTR [USELIN],0FFH ; Extended linear addressing?
  449.     JNZ    DOEXTS        ; Yes
  450.     MOV    AL,04H        ; Record type 04 extended linear addressing
  451.     JMP    SHORT BOTH    ; Continue
  452.                 ;
  453. DOEXTS:    MOV    AL,02H        ; Record type 02 extended addressing
  454. BOTH:    CALL    BITE        ; Send it
  455.     MOV    AX,[EXTEND]    ; Get current extended address
  456.     XCHG    AL,AH        ; Do high byte first
  457.     CALL    BITE        ; Send it
  458.     XCHG    AH,AL        ; Now do low byte
  459.     CALL    BITE        ; Send it
  460.     CMP    BYTE PTR [USELIN],0FFH ; Extended linear addressing
  461.     JNZ    DOEXTSS        ; Yes
  462.     ADD    WORD PTR [EXTEND],0001H    ; Bump to next block
  463.     JMP    SHORT BOTH1    ; Continue
  464.                 ;
  465. DOEXTSS:ADD    WORD PTR [EXTEND],1000H    ; Bump to next segment
  466. BOTH1:    MOV    AL,DL        ; Get checksum
  467.     CALL    BITE        ; Process, [clobbering dl]
  468.     MOV    AL,[ACR]    ; Get first terminator
  469.     STOSB            ; Append it
  470.     INC    BX        ; Bump output counter appropiately
  471.     CMP    [NUMTERM],BYTE PTR 02H ; Two terminations?
  472.     JNZ    SKIPLF2        ; No, skip
  473.     MOV    AL,[ALF]    ; Get second terminator
  474.     STOSB            ; Append it
  475.     INC    BX        ; Bump output counter appropiately
  476.                 ;
  477. SKIPLF2:MOV    CX,BX        ; Get count into cx
  478.     CALL    WRITE        ; Write output
  479.     POP    BX        ; Recover everything
  480.     POP    SI        ;
  481.     POP    DX        ;
  482.     POP    CX        ;
  483.     POP    DI        ;
  484.     POP    AX        ;
  485.     RET            ; Go home
  486.                 ;
  487. CHKOVR:    PUSH    AX        ; Save ax
  488.     MOV    AL,[OVERRIDE]    ; Check to see if extended override selected
  489.     OR    AL,AL        ; Force flags
  490.     JNZ    OVR        ; Overridden by user
  491.     MOV    AL,0FFH        ; Otherwise flag extended addressing
  492.     MOV    [USEEXT],AL    ; Flagged
  493. OVR:    POP    AX        ; Restore ax
  494.     RET            ; Go home
  495.                 ;
  496. FINISHUP:            ;
  497.     MOV    AH,2CH        ; Get time function
  498.     INT    21H        ; Go get it
  499.     MOV    AL,DL        ; Get hundreths of seconds
  500.     OR    AL,AL        ; Force flags
  501.     JPO    SKIP        ; Don't display
  502.     CALL    ILPRT        ; Print...
  503.         DB    CR,LF,'Dedicated to the Goddess Athena!',00H
  504.                 ;
  505. SKIP:    CALL    ILPRT        ; Print this...
  506.     DB    CR,LF,'Function Complete.',CR,LF,00H
  507.     MOV    AL,[OUTTYPE]    ; Get output format
  508.     OR    AL,AL        ; Force flags
  509.     JZ    HEXEND        ; Do hex
  510.                 ; Drop through to bnpf
  511.                 ;
  512. BNPFEND:LEA    DX,CNTRLC    ; Point to eof marker
  513.     MOV    CL,[NUMTERM]     ; Get number of termination characters...
  514.     XOR    CH,CH        ; Zero upper
  515.     INC    CX        ; To compensate for the cntrl-c!
  516.     CALL    DSKWRT        ; Write it
  517.     JNC    WOKK        ; Ok
  518.     JMP    BADWR        ; Error
  519.                 ;
  520. WARN:    CALL    ILPRT        ; Print this...
  521.     DB    CR,LF,LF,'WARNING:  Input data file too large for output size'
  522.     DB    ' selected.',07H,LF,00H    ;
  523.     JMP    FINISHUP    ; Terminate
  524.                 ;
  525. CNTRLC:                ;
  526.     DB    03H,CR,LF    ; Termination for bnpf
  527.                 ;
  528. HEXEND:    MOV    AL,[RAWHEX]    ; Check for raw hex
  529.     OR    AL,AL        ; Force flags
  530.     JNZ    WOKK        ; Raw hex does no end of file record either...
  531.                 ;
  532.     LEA    DX,EOFREC    ; Point to eof record
  533.     MOV    CX,000BH    ; Eleven bytes
  534.     ADD    CL,BYTE PTR [NUMTERM] ; Add in number of line terminations...
  535.     CALL    DSKWRT        ; Write it
  536.     JNC    WOKK        ; Ok
  537.     JMP    BADWR        ; Error
  538.                 ;
  539. ENDOF:                ;
  540.     DB    1AH        ; End of file mark
  541.                 ;
  542. WOKK:    MOV    AL,[DOEOF]    ; Do we want a ctrl-z?
  543.     OR    AL,AL        ; Force flags
  544.     JZ    NOEOF        ; No eof
  545.     LEA    DX,ENDOF    ; Point to eof
  546.     MOV    CX,0001H    ; One byte
  547.     CALL    DSKWRT        ; Write it
  548.                 ;
  549. NOEOF:    CALL    FLUSH        ; Force disk write
  550.     MOV    AH,3EH        ; Close the file now
  551.     MOV    BX,[OUTHDL]    ; Close output
  552.     INT    21H        ; Close the damn thing
  553.     JNC    CLOK        ; Closed ok
  554.     CALL    ILPRT        ; Print this...
  555.     DB    CR,LF,'Error Closing Output file!',00H
  556.                 ;
  557. CLOK:    MOV    AH,3EH        ; Close the file now
  558.     MOV    BX,[INHDL]    ; Close input
  559.     INT    21H        ; Close the damn thing
  560.     JNC    FINISH        ; Closed ok
  561.     CALL    ILPRT        ; Print this...
  562.     DB    CR,LF,'Error Closing Input file!',00H
  563.                 ;
  564. FINISH:    MOV    AX,4C00H    ; No-error termination
  565.     INT    21H        ; Bye-bye
  566.                 ;
  567. FINIS:    MOV    AX,4CFFH    ; Error termination
  568.     INT    21H        ; Bye-bye
  569.                 ;
  570. EOFREC:                ;
  571.     DB    ':00000001FF',CR,LF ; End of file record
  572.                 ;
  573. ;************************************************************************
  574. ;*                                    *
  575. ;*    ILPRT:    This is an 8088 in-line print routine.    It will print    *
  576. ;*    the string following the CALL NEAR instruction until a 00H is    *
  577. ;*    encountered.  Accepts:    Data string to print in memory following*
  578. ;*    the CALL NEAR used to invoke this routine.  Returns:  Nothing.    *
  579. ;*    Calls:    CONOUT.  Clobbers:  ES,SI                *
  580. ;*                                    *
  581. ;************************************************************************
  582.                 ;
  583. ILPRT:    PUSH    CS        ; Get code segment
  584.     POP    ES        ; Into es
  585.     POP    SI        ; Get offset
  586.     PUSH    AX        ; Save ax
  587.     PUSH    DX        ; And dx
  588. ILLP:    LODSB            ; Get char
  589.     OR    AL,AL        ; Force flags
  590.     JZ    ILEXIT        ; Exit if last
  591.     CALL    CONOUT        ; Send char
  592.     JMP    SHORT ILLP    ; Loop til done
  593. ILEXIT:    POP    DX        ; Restore dx
  594.     POP    AX        ; And ax
  595.     PUSH    SI        ; And return offset
  596.     RET            ; Near
  597.                 ;
  598. CONOUT:    MOV    AH,02H        ; Conout call
  599.     MOV    DL,AL        ; Get char
  600.     INT    21H        ; Do it
  601.     RET            ; Near
  602.                 ;
  603. BITE:    SUB    DL,AL        ; Generate checksum
  604.     PUSH    AX        ; Save
  605.     AND    AL,0F0H        ; Mask out lower nybble
  606.     ROR    AL,1        ; Get msn into lower nybble
  607.     ROR    AL,1        ; (8088 compatibility sucks...)
  608.     ROR    AL,1        ;
  609.     ROR    AL,1        ; Now it's there
  610.     CALL    NYB        ; Process nybble
  611.     MOV    [DI],AL        ; Save in disk buffer
  612.     INC    BX        ; Increment count
  613.     INC    DI        ; Next location in buffer
  614.     POP    AX        ; Recover byte
  615.     AND    AL,0FH        ; Mask lsn
  616.     CALL    NYB        ; Process nybble
  617.     MOV    [DI],AL        ; Save in disk buffer
  618.     INC    BX        ; Increment count
  619.     INC    DI        ; Next location in buffer
  620.     RET            ; Near
  621.                 ;
  622.                 ; Converts lower nybble in al to ascii hex
  623. NYB:    CMP    AL,0AH        ; Letter?
  624.     JNC    NYB1        ; Yes
  625.     ADD    AL,30H        ; Add in numeric bias
  626.     RET            ; Go home (near)
  627. NYB1:    ADD    AL,37H        ; Add in letter bias
  628.     RET            ; Go home (near)
  629.                 ;
  630. ;************************************************************************
  631. ;*                                    *
  632. ;*    DSKWRT:  This routine implements a double buffer disk write.    *
  633. ;*    It accepts the write request and blocks larger writes to    *
  634. ;*    the disk for increased performance.  Accepts: Pointer to ouput    *
  635. ;*    data in DX, byte count in CX.  Returns:  Status in carry flag,    *
  636. ;*    carry set if error.  Clobbers:    CX,AX,SI,DI.  Calls:  INT 21    *
  637. ;*                                    *
  638. ;************************************************************************
  639.                 ;
  640. DSKWRT:    MOV    SI,DX        ; Get data pointer in si
  641.     LEA    DI,REALOUT    ; Point to output buffer
  642.     ADD    DI,WORD    PTR [OUTPTR] ; Point to 1st free location
  643.     PUSH    CX        ; Save byte count
  644.     REP    MOVSB        ; Move the data
  645.     POP    CX        ; Get the byte count back
  646.     ADD    [OUTPTR],CX    ; Bump up counter/pointer
  647.     MOV    AX,[OUTPTR]    ; Get it
  648.     CMP    AX,16384D    ; Have we used at least 16k?
  649.     JGE    FLUSH        ; Yes we have, flush output buffer to disk
  650.     CLC            ; Everyone's ok
  651.     RET            ; Not yet
  652.                 ;
  653. FLUSH:    LEA    DX,REALOUT    ; Point to beginning of output buffer
  654.     MOV    BX,[OUTHDL]    ; Get output handle
  655.     MOV    AH,40H        ; Write function
  656.     MOV    CX,[OUTPTR]    ; Get output count
  657.     OR    CX,CX        ; Anything there?
  658.     JZ    NOFLUSH        ; Nope, don't bother
  659.     INT    21H        ; Do it
  660.     PUSHF            ; Save status
  661.     XOR    AX,AX        ; A zero
  662.     MOV    [OUTPTR],AX    ; Re-init output pointer/counter
  663.     POPF            ; Recover status
  664. NOFLUSH:RET            ; Go home
  665.                 ;
  666. ;************************************************************************
  667. ;*                                    *
  668. ;*    DSKRD:    This routine implements a double buffer disk read.    *
  669. ;*    It accepts the 32 byte read request and deblocks larger     *
  670. ;*    reads from the disk for increased performance.    Accepts:    *
  671. ;*    Place to stuff this stuff in DX.  Returns:  Status in        *
  672. ;*    carry flag, carry set if error, Number of bytes returned in AX. *
  673. ;*    This number will only be smaller than 32 at the end of the    *
  674. ;*    input file. Clobbers:  CX,AX,SI,DI.  Calls:  INT 21        *
  675. ;*                                    *
  676. ;************************************************************************
  677.                 ;
  678. DSKRD:    MOV    DI,DX        ; Get destination
  679.     LEA    SI,REALIN    ; Point to input buffer
  680.     ADD    SI,WORD    PTR [INPTR] ; Add in pointer
  681.     MOV    CX,[INCNT]    ; Get number of bytes left
  682.     OR    CX,CX        ; Force flags
  683.     JZ    RD        ; Outta data here, go get more from disk
  684.     CMP    CX,32D        ; How many?
  685.     JL    LAST        ; Last time through
  686.     MOV    CX,32D        ; Xfer 32 bytes
  687.     REP    MOVSB        ; Move bytes into program's input buffer
  688.     MOV    AX,32D        ; We moved 32 bytes
  689.     ADD    [INPTR],AX    ; Bump up input pointer
  690.     SUB    [INCNT],AX    ; Bump down input count
  691.     CLC            ; Clear carry
  692.     RET            ; Go home
  693.                 ;
  694. LAST:    REP    MOVSB        ; Move bytes into program's input buffer
  695.     MOV    AX,[INCNT]    ; Last number of bytes moved
  696.     XOR    CX,CX        ; A zero
  697.     MOV    [INCNT],CX    ; No more avail
  698.     MOV    [INPTR],CX    ; Zero pointer
  699.     CLC            ; Clear carry
  700.     RET            ; Go home
  701.                 ;
  702. RD:    PUSH    DX        ; Save program's input pointer
  703.     LEA    DX,REALIN    ; Point to buffer
  704.     MOV    CX,4096D    ; Read another 4k bytes
  705.     MOV    BX,[INHDL]    ; Get handle
  706.     MOV    AH,3FH        ; Read function
  707.     INT    21H        ; Do it
  708.     POP    DX        ; Recover program's input pointer
  709.     JNC    RD1        ; If error, return immediately
  710.     RET            ; Go away
  711.                 ;
  712. RD1:    XOR    CX,CX        ; Get a zero
  713.     MOV    [INPTR],CX    ; Zero input pointer
  714.     MOV    [INCNT],AX    ; Init number of bytes avail
  715.     OR    AX,AX        ; Force flags
  716.     JNZ    DSKRD        ; Recursively re-enter routine if any data
  717.     RET            ; No data, program will handle...
  718.                 ;
  719. INHDL:                ;
  720.     BLKB    2        ; Storage for input file handle
  721. OUTHDL:                ;
  722.     BLKB    2        ; Storage for output file handle
  723. ADDRESS:            ;
  724.     DW    0000H        ; Current address
  725. EXTEND:                ;
  726.     DW    0000H        ; Current extended address
  727. OUTPTR:                ;
  728.     DW    0000H        ; Output pointer
  729. INPTR:                ;
  730.     DW    0000H        ; Input buffer pointer
  731. INCNT:                ;
  732.     DW    0000H        ; Bytes left in buffer
  733. INFN:    EQU    $        ; 64 bytes input filename storage
  734. OUTFN:    EQU    INFN+64D    ; Plenty of room for a filename & path
  735. INBUF:    EQU    OUTFN+64D    ; Thirty two byte input buffer
  736. OUTBUF:    EQU    INBUF+32D    ; 128 byte output buffer
  737. REALIN:    EQU    OUTBUF+128D    ; 4k 'real' input buffer
  738. REALOUT:EQU    REALIN+4096D    ; All these buffers overlay the help file
  739.                 ;
  740. HELP:                ; Called only if nothing is going to happen
  741.                 ; Otherwise, this routine is overwritten
  742.     MOV    AX,[BNPFTYP]    ; Check for change to bnpf
  743.     CMP    AX,'NP'        ; Un-changed?
  744.     JZ    YES        ; Yes
  745.     MOV    [BNPFPATCH],AX    ; No, patch instructions
  746.     MOV    [BNPFPTCH],AX    ; Again
  747. YES:    LEA    SI,FTYPE    ; Point to hex filename
  748.     LEA    DI,F        ; Point to hex filename in instructions
  749.     MOV    CX,0002H    ; 2 words = 4 bytes
  750.     REP    MOVSW        ; Move them
  751.                 ;
  752.     LEA    SI,FTYPE1    ; Point to bnpf filename
  753.     LEA    DI,F1        ; Point to bnpf filename in instructions
  754.     MOV    CX,0002H    ; 2 words = 4 bytes
  755.     REP    MOVSW        ; Move them
  756.     JMP    SHORT NEXT    ; Self-modifying code, flush queu
  757. NEXT:    CALL    ILPRT        ; Print help screen
  758.     DB    ', Binary --> Intel hex or Binary --> BNPF conversion.'
  759.     DB    CR,LF,'Usage:  UNLOAD86 FILENAME.TYP [/OPTIONS]                 '
  760.     DB    CR,LF,'Where Options are:'
  761.     DB    CR,LF,'     B for B'
  762. BNPFPTCH:            ;
  763.     DB    'NPF instead of INTeL hex.'
  764.     DB    CR,LF,'     H for raw ASCII hex output'
  765.     DB    CR,LF,'     E to use extended addressing on files <=64K'
  766.     DB    CR,LF,'     L to use extended linear addressing'
  767.     DB    CR,LF,'     O to override forced extended addressing.'
  768.     DB    CR,LF,'     Z to place a Control-Z at end of file.'
  769.     DB    CR,LF,'     U for LF only UNIX style output'
  770.     DB    CR,LF,'     T for CR only TRS-80/MACintosh style output'
  771.     DB    CR,LF,'     P to fill output file to end of EPROM.'
  772.     DB    CR,LF,'       Uses the following subcommands:'
  773.     DB    CR,LF,'         0  32 Bytes         1  64 Bytes'
  774.     DB    CR,LF,'         2  128 Bytes        3  256 Bytes'
  775.     DB    CR,LF,'         4  512 Bytes        5  1K Bytes'
  776.     DB    CR,LF,'         6  2K Bytes         7  4K Bytes'
  777.     DB    CR,LF,'         8  8K Bytes         9  16K Bytes'
  778.     DB    CR,LF,'         A  32K Bytes        B  64K Bytes'
  779.     DB    CR,LF,'         C  *128K Bytes      D  *256K Bytes'
  780.     DB    CR,LF,'         E  *512K Bytes      F  *1Meg Bytes'
  781.     DB    CR,LF,'         * Forces extended addressing'
  782.     DB    CR,LF,'INTeL hex output files are '
  783. F:                ; Self patch instructions
  784.     DB    '.HEX'        ;
  785.     DB    '      B'    ;
  786. BNPFPATCH:            ;
  787.     DB    'NP'        ;
  788.     DB    'F output files are '
  789. F1:                ; Self patch instructions
  790.     DB    '.BNP'        ;
  791.     DB    CR,LF,'Note:  - or [ may be used instead of / for switches.',00H
  792.     JMP    FINIS        ; Terminate
  793.                 ;
  794. ATABLE:                ; Table of rom sizes for fillrom option
  795.     DW    0000H        ; Segment for 32 byter
  796.     DW    001FH        ; Address for 32 byter
  797.     DW    0000H        ; Segment for 64 byter
  798.     DW    003FH        ; Address for 64 byter
  799.     DW    0000H        ; Segment for 128 byter
  800.     DW    007FH        ; Address for 128 byter
  801.     DW    0000H        ; Segment for 256 byter
  802.     DW    00FFH        ; Address for 256 byter
  803.     DW    0000H        ; Segment for 512 byter
  804.     DW    01FFH        ; Address for 512 byter
  805.     DW    0000H        ; Segment for 1k byter
  806.     DW    03FFH        ; Address for 1k byter
  807.     DW    0000H        ; Segment for 2k byter
  808.     DW    07FFH        ; Address for 2k byter
  809.     DW    0000H        ; Segment for 4k byter
  810.     DW    0FFFH        ; Address for 4k byter
  811.     DW    0000H        ; Segment for 8k byter
  812.     DW    1FFFH        ; Address for 8k byter
  813.     DW    0000H        ; Segment for 16k byter
  814.     DW    3FFFH        ; Address for 16k byter
  815.     DW    0000H        ; Segment for 32k byter
  816.     DW    7FFFH        ; Address for 32k byter
  817.     DW    0000H        ; Segment for 64k byter
  818.     DW    0FFFFH        ; Address for 64k byter
  819.     DW    1000H        ; Segment for 128k byter
  820.     DW    0FFFFH        ; Address for 128k byter
  821.     DW    3000H        ; Segment for 256k byter
  822.     DW    0FFFFH        ; Address for 256k byter
  823.     DW    7000H        ; Segment for 512k byter
  824.     DW    0FFFFH        ; Address for 512k byter
  825.     DW    0F000H        ; Segment for 1m byter
  826.     DW    0FFFFH        ; Address for 1m byter
  827.                 ;
  828.     END            ;
  829.